package com.haima.sage.bigdata.api.frame.condition.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.haima.sage.bigdata.api.frame.condition.ConditionGroup;
import com.haima.sage.bigdata.api.frame.condition.OperatorType;

public class ConditionGroupService extends ConditionService<ConditionGroup> {
    private static final Logger LOG = LogManager.getLogger(ConditionGroupService.class);

    private List<ConditionService<?>> services = new ArrayList<>();

    public ConditionGroupService(ConditionGroup group) {
        super(group);
        if (group.getConditions() != null) {
            group.getConditions().forEach(condition -> {
                ConditionService<?> service = condition.service();
                services.add(service);
            });
        }
    }

    @Override
    public boolean deal(Map<?, ?> event) {
        try {
            if (OperatorType.AND == config.getOperator()) {
                return dealEventAND(event);
            } else if (OperatorType.OR == config.getOperator()) {
                return dealEventOR(event);
            } else if (OperatorType.NOT == config.getOperator()) {
                return dealEventNOT(event);
            }
        } catch (Exception e) {
            LOG.debug("dealConditionGroup fail", e);
        }
        return false;
    }

    @Override
    public boolean deal(String raw) {
        try {
            if (OperatorType.AND == config.getOperator()) {
                return dealRawAND(raw);
            } else if (OperatorType.OR == config.getOperator()) {
                return dealRawOR(raw);
            } else if (OperatorType.NOT == config.getOperator()) {
                return dealRawNOT(raw);
            }
        } catch (Exception e) {
            LOG.debug("deal Condition group fail", e);
        }
        return false;
    }


    private boolean dealEventNOT(Map<?, ?> event) throws Exception {
        ConditionService<?> service = services.get(0);
        return !service.deal(event);
    }

    private boolean dealRawNOT(String raw) throws Exception {
        ConditionService<?> service = services.get(0);
        return !service.deal(raw);
    }

    private boolean dealEventOR(Map<?, ?> event) throws Exception {
        for (ConditionService<?> service : services) {
            if (service.deal(event)) {
                return true;
            }
        }
        return false;
    }

    private boolean dealRawOR(String raw) throws Exception {
        for (ConditionService<?> service : services) {
            if (service.deal(raw)) {
                return true;
            }
        }
        return false;
    }

    /**
     * AND运算，任一项判断为false最终为false。
     *
     */
    private boolean dealEventAND(Map<?, ?> event) throws Exception {
        for (ConditionService<?> service : services) {
            if (!service.deal(event)) {
                return false;
            }
        }
        return true;
    }

    private boolean dealRawAND(String raw) throws Exception {
        for (ConditionService<?> service : services) {
            if (!service.deal(raw)) {
                return false;
            }
        }
        return true;
    }

}
